"""
Case Type   : 小型化
Case Name   : 时间向后跳变，开启审计功能开关，移除审计文件
Create At   : 2024/12/23
Owner       : wan005
Description :
    1.root用户注入时间跳变故障
    2.获取起止时间内的审计信息
    3.查看审计信息
    4.移除审计文件
    5.获取起止时间内的审计信息
    6.查看审计信息
    7.检查审计文件是否生成
    8.移除审计文件
    9.还原时间跳变故障
    10.执行登陆数据库操作
    11.检查审计文件是否生成
Expect      :
    1.故障构造成功
    2.获取成功
    3.查看到审计信息
    4.移除审计文件成功
    5.获取成功
    6.查看到审计信息
    7.审计文件生成
    8.移除审计文件成功
    9.还原时间成功
    10.执行成功
    11.文件生成成功
History     :
"""
import os
import time
import unittest
from testcase.utils.ComInstall import LiteInstall, LiteUnInstall
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class Lite(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pkg_path = os.path.dirname(macro.DB_SCRIPT_PATH)
        self.com_install = LiteInstall(self.pkg_path, None, None)
        self.com_uninstall = LiteUnInstall(self.pkg_path)
        self.root_node = Node('PrimaryRoot')
        self.user_node = Node('PrimaryDbUser')
        self.user = None
        self.port = None

    def test_audit(self):
        text = '----prestep1:获取可用用户和端口;expect:获取成功----'
        self.log.info(text)
        self.user, self.port = self.com_install.get_user_and_port(self.root_node)
        self.log.info(f'self.user:{self.user}, self.port:{self.port}')
        self.user_node.ssh_user = self.user
        self.user_node.ssh_password = macro.COMMON_PASSWD
        self.data_path = os.path.join('/home', self.user, 'data')
        self.app_path = os.path.join('/home', self.user, 'app')
        self.audit_path = os.path.join(self.data_path, 'pg_audit')
        self.com_install.data_path = self.data_path
        self.com_install.app_path = self.app_path

        text = '----prestep2:创建数据库用户和用户组;expect:创建成功----'
        self.log.info(text)
        self.com_install.prepare_user(self.user, self.root_node)

        text = '----prestep3:获取数据库安装包并解压;expect:成功----'
        self.log.info(text)
        res = self.com_install.tar_pkg(self.root_node)
        self.assertIn('install.sh', res, f'执行失败: {text}')

        text = '----prestep4:执行脚本安装数据库;expect:安装成功----'
        self.log.info(text)
        res = self.com_install.install_single(self.user_node, self.port)
        self.log.info(res)
        self.assertIn('start datanode success', res, f'执行失败: {text}')

        text = '----step1:root用户注入时间跳变故障;expect:获取成功----'
        self.log.info(text)
        exe_cmd1 = "date -s '10 min ago' +'%Y-%m-%d %H:%M:%S'"
        exe_msg1 = self.root_node.sh(exe_cmd1).result()
        self.log.info(exe_msg1)

        text = '----step2:获取起止时间内的审计信息;expect:获取成功----'
        self.log.info(text)
        text = '----获取起始时间----'
        self.log.info(text)
        date_cmd2_1 = f'SELECT sysdate;'
        start_cmd2 = f'gsql -d postgres -p {self.port} -c "{date_cmd2_1}"'
        self.log.info(start_cmd2)
        start_msg2 = self.user_node.sh(start_cmd2).result()
        start_time2 = start_msg2.splitlines()[-2].strip()
        self.log.info(start_time2)
        text = '----执行sql语句----'
        time.sleep(2)
        self.log.info(text)
        login_cmd2 = f'gsql -d postgres -p {self.port} -c "\\q"'
        self.log.info(login_cmd2)
        login_res2 = self.user_node.sh(login_cmd2).result()
        self.log.info(login_res2)
        time.sleep(6)
        text = '----获取结束的时间----'
        self.log.info(text)
        date_cmd2_2 = 'SELECT sysdate;'
        end_cmd2 = f'gsql -d postgres -p {self.port} -c "{date_cmd2_2}"'
        self.log.info(end_cmd2)
        end_msg2 = self.user_node.sh(end_cmd2).result()
        end_time2 = end_msg2.splitlines()[-2].strip()
        self.log.info(end_time2)

        text = '----step3.查看审计信息;expect:查看成功----'
        self.log.info(text)
        sql_cmd3 = f"select * from pg_query_audit('{start_time2}'," \
                   f"'{end_time2}') where username='{self.user}';"
        exe_cmd3 = f"gsql -d postgres -p {self.port} -c \"{sql_cmd3}\""
        self.log.info(exe_cmd3)
        res3 = self.user_node.sh(exe_cmd3).result()
        self.log.info(res3)
        self.assertIn('login_success', res3, '执行失败:' + text)
        self.assertIn('user_logout', res3, '执行失败:' + text)

        text = '----step4.移除审计文件;expect:成功----'
        self.log.info(text)
        ls_file4 = f'ls {os.path.join(self.audit_path, "*adt")} |tail -1'
        ls_msg4 = self.user_node.sh(ls_file4).result()
        self.log.info(ls_msg4)
        rm_cmd4 = f'rm -rf {ls_msg4}'
        self.log.info(rm_cmd4)
        rm_res4 = self.user_node.sh(rm_cmd4).result()
        self.log.info(rm_res4)
        self.assertEqual('', rm_res4, '执行失败:' + text)

        text = '----step5:获取起止时间内的审计信息;expect:获取成功----'
        self.log.info(text)
        text = '----获取起始时间----'
        self.log.info(text)
        sql_cmd5_1 = f'SELECT sysdate;'
        start_cmd5 = f'gsql -d postgres -p {self.port} -c "{sql_cmd5_1}"'
        self.log.info(start_cmd5)
        start_msg5 = self.user_node.sh(start_cmd5).result()
        start_time5 = start_msg5.splitlines()[-2].strip()
        self.log.info(start_time5)
        text = '----执行sql语句----'
        time.sleep(2)
        self.log.info(text)
        login_cmd5 = f'gsql -d postgres -p {self.port} -c "\\q"'
        self.log.info(login_cmd5)
        login_res5 = self.user_node.sh(login_cmd5).result()
        self.log.info(login_res5)
        time.sleep(6)
        text = '----获取结束的时间----'
        self.log.info(text)
        sql_cmd5_2 = 'SELECT sysdate;'
        end_cmd5 = f'gsql -d postgres -p {self.port} -c "{sql_cmd5_2}"'
        self.log.info(end_cmd5)
        end_msg5 = self.user_node.sh(end_cmd5).result()
        end_time5 = end_msg5.splitlines()[-2].strip()
        self.log.info(end_time5)

        text = '----step6.查看审计信息;expect:查看成功----'
        self.log.info(text)
        sql_cmd6 = f"select * from pg_query_audit('{start_time5}'," \
                   f"'{end_time5}') where username='{self.user}';"
        exe_cmd6 = f"gsql -d postgres -p {self.port} -c \"{sql_cmd6}\""
        self.log.info(exe_cmd6)
        res6 = self.user_node.sh(exe_cmd6).result()
        self.log.info(res6)
        self.assertIn('login_success', res6, '执行失败:' + text)
        self.assertIn('user_logout', res6, '执行失败:' + text)

        text = '----step7.查看审计文件是否生成;expect:成功----'
        self.log.info(text)
        ls_file7 = f'ls {os.path.join(self.audit_path, "*adt")} |tail -1'
        ls_msg7 = self.user_node.sh(ls_file7).result()
        self.assertEqual('_adt', ls_msg7[-4:], '执行失败:' + text)

        text = '----step8.移除审计文件;expect:成功----'
        self.log.info(text)
        ls_file8 = f'ls {os.path.join(self.audit_path, "*adt")} |tail -1'
        ls_msg8 = self.user_node.sh(ls_file8).result()
        self.log.info(ls_msg8)
        rm_cmd8 = f'rm -rf {ls_msg8}'
        self.log.info(rm_cmd8)
        rm_res8 = self.user_node.sh(rm_cmd8).result()
        self.log.info(rm_res8)
        self.assertEqual('', rm_res8, '执行失败:' + text)

        text = '----step9:还原时间跳变故障;expect:获取成功----'
        self.log.info(text)
        exe_cmd9 = "date -s '10 min' +'%Y-%m-%d %H:%M:%S'"
        exe_msg9 = self.root_node.sh(exe_cmd9).result()
        self.log.info(exe_msg9)

        text = '----step10:执行登陆数据库操作;expect:获取成功----'
        self.log.info(text)
        login_cmd10 = f'gsql -d postgres -p {self.port} -c "\\q"'
        self.log.info(login_cmd10)
        login_res10 = self.user_node.sh(login_cmd10).result()
        self.log.info(login_res10)

        text = '----step11.检查审计文件是否生成;expect:成功----'
        self.log.info(text)
        ls_file11 = f'ls {os.path.join(self.audit_path, "*adt")} |tail -1'
        ls_msg11 = self.user_node.sh(ls_file11).result()
        self.log.info(ls_msg11)
        self.assertEqual('_adt', ls_msg11[-4:], '执行失败:' + text)

    def tearDown(self):
        text = '-----清理环境-----'
        self.log.info(text)
        res = self.com_uninstall.uninstall(self.user_node)
        self.com_uninstall.clear_env(self.root_node)
        self.assertIn('success', res, f'执行失败: {text}')
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
